<template>
  <div>
    <a-card class="data-card">
      <div class="personbox">
        <div class="perlistbox">
          <!-- 表格数据 -->
          <a-row>
            <a-col :span="1.2">
              <a-button @click="openAdd()" type="primary">
                <template #icon>
                  <icon-plus />
                </template>
                添加部位
              </a-button>
            </a-col>
          </a-row>
          <a-table
            style="margin-top: 10px"
            :columns="columns"
            :data="data"
            :expandable="expandable"
            :bordered="false"
          />
        </div>
        <div class="box">
          <canvas id="myCanvas" width="420" height="700"></canvas>
        </div>
        <div class="bocdd">
          <a-card title="CT">
            <template #extra>
              <a-link></a-link>
            </template>

            <div class="bocdds">
              <a-button type="primary" @click="startBiaoZhu">开始标注</a-button>
              <a-button type="primary" @click="clearCache">重置标记</a-button>
              <a-button type="primary" @click="toggleLinesAndText"
                >显示旗标</a-button
              >
            </div>
          </a-card>
        </div>
      </div>
    </a-card>

    <!-- 添加标记的输入框 -->
    <div
      v-if="currentMarker && canBiaoZhu"
      class="input-container edit-panel"
      :style="{ left: editPanelX + 'px', top: editPanelY + 'px' }"
    >
      <input v-model="currentText" placeholder="输入文字" />
      <a-button @click="addTextAndCompleteMarker">添加</a-button>
      <a-button @click="confirmaddTextAndCompleteMarker">取消</a-button>
    </div>

    <!-- 编辑标记的面板 -->
    <div
      v-if="editingMarker"
      class="edit-panel"
      :style="{ left: editPanelX + 'px', top: editPanelY + 'px' }"
    >
      <input type="text" v-model="currentText" />
      <a-button @click="confirmEdit">确认</a-button>
      <a-button @click="cancelEditing">取消</a-button>
      <!-- 新增取消按钮 -->
      <a-button @click="deleteMarker">删除</a-button>
    </div>
    <!-- 新增/修改图谱名称 -->
    <a-modal
      v-model:visible="addShow"
      @cancel="handleCancel"
      :on-before-ok="handleCheck"
      :mask-closable="false"
      unmountOnClose
    >
      <template #title> 部位 </template>
      <a-form ref="addModel" :rules="rules" :model="addForm">
        <a-form-item field="name" label="部位名称">
          <a-input
            v-model="addForm.name"
            size="large"
            placeholder="请输入部位名称"
          />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        rules: {
          name: [
            {
              required: true,
              message: '请输入专业名称',
            },
          ],
        },
        data: [
          {
            key: '1',
            name: '部位1',
          },
        ],
        columns: [
          {
            title: '部位名称',
            dataIndex: 'name',
          },
          {
            title: '是否标记',
            dataIndex: 'name',
          },
        ],
        imgsrc: [],
        addShow: false,
        canBiaoZhu: false,
        pointColor: 'red',
        pointSize: 10,
        imgScale: 1,
        zoomStep: 0.1,
        permarkers: [],
        canvas: null,
        ctx: null,
        img: null,
        imgWidth: 420,
        imgHeight: 700,
        currentText: '',
        currentMarker: null,
        showLinesAndText: true,
        isDragging: false,
        startDragX: 0,
        startDragY: 0,
        imgOffsetX: 0,
        imgOffsetY: 0,
        isSpacePressed: false,
        hoveredMarker: null,
        editingMarker: false,
        editPanelX: 0,
        editPanelY: 0,
        addflag: false,
        dcomid: 1,
        addForm: [{ name: '' }],
      };
    },
    methods: {
      openAdd() {
        this.addShow = true;
      },
      cancelEditing() {
        this.editingMarker = false;
        this.draw();
      },
      checkHover(x, y) {
        const { permarkers, pointSize, imgScale, imgOffsetX, imgOffsetY } =
          this;
        // console.log('鼠标带的', permarkers)
        // 查找当前标记点
        const targetElement = permarkers.find(
          (item) => item.dcomid == this.dcomid
        );
        if (targetElement) {
          this.hoveredMarker = targetElement.bsdata.find((marker) => {
            const markerX = marker.x * imgScale + imgOffsetX;
            const markerY = marker.y * imgScale + imgOffsetY;

            const isHoveringMarker =
              Math.hypot(x - markerX, y - markerY) < (pointSize / 2) * imgScale;

            if (isHoveringMarker) return true;

            const isMarkerLeft =
              markerX < (this.canvas.width - 50) / 2 + 50 / 2;
            const lineLength = 100 * imgScale;
            const lineEndX = isMarkerLeft
              ? markerX - lineLength
              : markerX + lineLength;
            const lineEndY = markerY;

            const distanceToLine =
              Math.abs(
                (lineEndY - markerY) * x -
                  (lineEndX - markerX) * y +
                  lineEndX * markerY -
                  lineEndY * markerX
              ) / Math.hypot(lineEndY - markerY, lineEndX - markerX);

            if (distanceToLine < 10 * imgScale) {
              const textWidth = this.ctx.measureText(marker.text).width;
              const textHeight = 14 * imgScale;
              const textPadding = 10 * imgScale;
              const textX =
                lineEndX +
                (isMarkerLeft ? -textWidth - textPadding : textPadding);
              const textY = lineEndY + 5 * imgScale;

              return (
                x >= textX &&
                x <= textX + textWidth &&
                y >= textY - textHeight &&
                y <= textY
              );
            }

            return false;
          });
        }
      },
      handleMouseMove(e) {
        // console.log('检测到移动鼠标', e)

        const canvasX = e.offsetX;
        const canvasY = e.offsetY;

        if (this.isDragging) {
          this.dragMove(e); // 拖拽逻辑
        } else {
          this.checkHover(canvasX, canvasY); // 其他鼠标移动逻辑（例如检查悬停）
          this.draw(); // 绘制更新
        }
      },
      handleCanvasClick(e) {
        // console.log('点击了文字', this.canBiaoZhu)
        if (this.canBiaoZhu) {
          // console.log('点击了文字2', this.canBiaoZhu)
          const canvasX = e.offsetX;
          const canvasY = e.offsetY;

          const imgX =
            (canvasX -
              (this.canvas.width / 2 - (this.imgWidth * this.imgScale) / 2)) /
            this.imgScale;
          const imgY =
            (canvasY -
              (this.canvas.height / 2 - (this.imgHeight * this.imgScale) / 2)) /
            this.imgScale;
          this.createMarker(imgX, imgY);
          this.editPanelX = e.clientX; // 可以保留 clientX/y，用于显示面板
          this.editPanelY = e.clientY;
        } else if (this.hoveredMarker) {
          this.currentMarker = this.hoveredMarker;
          this.currentText = this.currentMarker.text;
          this.editingMarker = true;
          this.editPanelX = e.clientX; // 可以保留 clientX/y，用于显示面板
          this.editPanelY = e.clientY;
        }
      },
      createMarker(x, y) {
        if (this.canBiaoZhu) {
          this.addflag = true;
          this.currentMarker = { x, y, color: this.pointColor };
          this.draw();
        }
      },
      startBiaoZhu() {
        this.addflag = true;
        this.canBiaoZhu = true;
        this.currentMarker = null;
        this.editingMarker = false;
      },
      addTextAndCompleteMarker() {
        this.editingMarker = false;
        if (this.currentText.trim() === '') return;
        if (this.currentMarker) {
          this.currentMarker.text = this.currentText.trim();
          this.currentText = '';

          // 假设 this.permarkers 是一个数组，this.dcomid 是要查找的 dcomid，this.currentMarker 是要添加的新数据
          const existingMarker = this.permarkers.find(
            (marker) => marker.dcomid === this.dcomid
          );

          if (existingMarker) {
            // 如果找到相同 dcomid 的对象，直接向其 bsdata 数组中添加新的数据
            existingMarker.bsdata.push(this.currentMarker);
          } else {
            // 如果没有找到相同 dcomid 的对象，创建新的对象并添加到 permarkers 数组中
            this.permarkers.push({
              dcomid: this.dcomid,
              bsdata: [this.currentMarker],
            });
          }

          // this.permarkers.push({ dcomid: this.dcomid, bsdata: [this.currentMarker] })
          this.currentMarker = null;
          this.saveMarkers();
          this.canBiaoZhu = false;
          this.draw();
        }
      },
      confirmaddTextAndCompleteMarker() {
        this.editingMarker = false;
        this.currentText = '';
        this.canBiaoZhu = false;
        this.addflag = false;
      },
      confirmEdit() {
        this.addflag = false;
        if (this.currentText.trim() == '') return;
        if (this.currentMarker) {
          this.currentMarker.text = this.currentText.trim();
          this.saveMarkers();
          this.editingMarker = false;
          this.currentText = '';
          this.draw();
        }
      },
      deleteMarker() {
        if (this.currentMarker) {
          // 查找当前标记所在的 dcomid 对应的对象
          const markerGroup = this.permarkers.find(
            (marker) => marker.dcomid === this.dcomid
          );

          if (markerGroup) {
            // 从 dcomid 对应的 bsdata 数组中删除当前标记
            markerGroup.bsdata = markerGroup.bsdata.filter(
              (marker) => marker !== this.currentMarker
            );

            // 如果 bsdata 数组为空，删除该 dcomid 对应的对象
            if (markerGroup.bsdata.length === 0) {
              this.permarkers = this.permarkers.filter(
                (marker) => marker.dcomid !== this.dcomid
              );
            }

            // 重新设置当前标记和文本
            this.currentMarker = null;
            this.currentText = '';
            this.saveMarkers(); // 保存更新后的标记
            this.editingMarker = false;
            this.draw(); // 重新绘制画布
          }
        }
      },

      draw() {
        // 处理图片逻辑

        if (!this.img.complete || this.img.naturalWidth === 0) {
          return;
        }

        const canvas = this.canvas;
        const ctx = this.ctx;
        const img = this.img;

        ctx.clearRect(0, 0, canvas.width, canvas.height);

        // Calculate scaled image dimensions
        const scaledWidth = this.imgWidth * this.imgScale;
        const scaledHeight = this.imgHeight * this.imgScale;

        // Calculate image offset on the canvas
        const xOffset = (canvas.width - scaledWidth) / 2;
        const yOffset = (canvas.height - scaledHeight) / 2;

        // Draw the image
        ctx.drawImage(img, xOffset, yOffset, scaledWidth, scaledHeight);
        this.permarkers.forEach((item) => {
          if (item.dcomid == this.dcomid) {
            item.bsdata.forEach((marker) => {
              const markerX = marker.x * this.imgScale + xOffset;
              const markerY = marker.y * this.imgScale + yOffset;

              const isMarkerLeft = markerX < (canvas.width - 50) / 2 + 50 / 2;
              const lineLength = 100 * this.imgScale;
              const lineEndX = isMarkerLeft
                ? markerX - lineLength
                : markerX + lineLength;
              const lineEndY = markerY;

              const isHovered = marker === this.hoveredMarker;

              if (this.showLinesAndText) {
                // Draw marker point
                ctx.fillStyle = isHovered ? 'yellow' : marker.color;
                ctx.beginPath();
                ctx.arc(markerX, markerY, this.pointSize / 2, 0, 2 * Math.PI);
                ctx.fill();

                // Draw line
                ctx.strokeStyle = isHovered ? 'yellow' : marker.color;
                ctx.lineWidth = 1.5;
                ctx.beginPath();
                ctx.moveTo(markerX, markerY);
                ctx.lineTo(lineEndX, lineEndY);
                ctx.stroke();

                // Draw text
                ctx.fillStyle = isHovered ? 'yellow' : 'green';
                ctx.font = `${14 * this.imgScale}px Arial`;
                const textPadding = 10 * this.imgScale;
                const textWidth = ctx.measureText(marker.text).width;
                const textX =
                  lineEndX +
                  (isMarkerLeft ? -textWidth - textPadding : textPadding);
                const textY = lineEndY + 5 * this.imgScale;

                ctx.fillText(marker.text, textX, textY);
              } else {
                // Draw marker point without line and text
                ctx.fillStyle = isHovered ? 'yellow' : marker.color;
                ctx.beginPath();
                ctx.moveTo(markerX, markerY);
                ctx.lineTo(markerX - 10, markerY - 20);
                ctx.lineTo(markerX + 10, markerY - 20);
                ctx.closePath();
                ctx.fill();
              }
            });
          }
        });

        if (
          this.currentMarker &&
          !this.editingMarker &&
          this.currentText === '' &&
          this.addflag
        ) {
          const { x, y } = this.currentMarker;
          const markerX = x * this.imgScale + xOffset;
          const markerY = y * this.imgScale + yOffset;

          if (this.showLinesAndText) {
            // Draw new marker point
            ctx.fillStyle = this.pointColor;
            ctx.beginPath();
            ctx.arc(markerX, markerY, this.pointSize / 2, 0, 2 * Math.PI);
            ctx.fill();

            // Draw line
            const isMarkerLeft = markerX < (canvas.width - 50) / 2 + 50 / 2;
            const lineLength = 150 * this.imgScale;
            const lineEndX = isMarkerLeft
              ? markerX - lineLength
              : markerX + lineLength;
            const lineEndY = markerY;

            ctx.strokeStyle = this.pointColor;
            ctx.lineWidth = 1.5;
            ctx.beginPath();
            ctx.moveTo(markerX, markerY);
            ctx.lineTo(lineEndX, lineEndY);
            ctx.stroke();

            // Draw placeholder text
            ctx.fillStyle = 'red';
            ctx.font = `${12 * this.imgScale}px Arial`;
            ctx.fillText(
              '请输入新建标记点',
              lineEndX +
                (isMarkerLeft
                  ? 10
                  : -10 - ctx.measureText('请输入新建标记点').width),
              lineEndY - 10
            );
          } else {
            // Draw new marker point without line and text
            ctx.fillStyle = this.pointColor;
            ctx.beginPath();
            ctx.moveTo(markerX, markerY);
            ctx.lineTo(markerX - 10, markerY - 20);
            ctx.lineTo(markerX + 10, markerY - 20);
            ctx.closePath();
            ctx.fill();
          }
        }
      },
      // 保存标记到本地缓存
      saveMarkers() {
        localStorage.setItem('permarkers', JSON.stringify(this.permarkers));
      },
      // 加载本地缓存的标记
      loadMarkers() {
        const cachedMarkers = localStorage.getItem('permarkers');
        if (cachedMarkers) {
          this.permarkers = JSON.parse(cachedMarkers);
          this.draw();
        }
      },
      // 清除本地缓存
      clearCache() {
        localStorage.removeItem('permarkers');
        this.permarkers = [];
        this.draw();
      },
      // 切换显示旗标和文本
      toggleLinesAndText() {
        this.showLinesAndText = !this.showLinesAndText;
        this.draw();
      },
    },
    mounted() {
      this.canvas = document.getElementById('myCanvas');
      this.ctx = this.canvas.getContext('2d');
      this.img = new Image();
      // console.log('加载一下图片', ())

      this.imgsrc = [
        {
          id: 1,
          src: './r.png',
        },
      ];

      this.img.src = this.imgsrc[0].src;
      this.img.onload = () => {
        this.loadMarkers();
        this.draw();
      };

      // 事件绑定
      this.canvas.onmousemove = (e) => this.handleMouseMove(e);
      this.canvas.addEventListener('click', (e) => this.handleCanvasClick(e));
      // 添加滚轮事件监听器
    },

    beforeDestroy() {
      // 事件解绑
      this.canvas.removeEventListener('mousemove', this.handleMouseMove);
      this.canvas.removeEventListener('click', this.handleCanvasClick);
    },
  };
</script>

<style scoped>
  .perlistbox {
    width: 900px;
    height: 100%;
    /* background-color: red; */
  }
  .personbox {
    display: flex;
  }
  #myCanvas {
    border: solid 1px #00ff80;
    /* background-color: red; */
  }

  .edit-panel {
    position: absolute;
    background-color: white;
    border: 1px solid #ddd;
    padding: 10px;
    border-radius: 4px;
  }
  .box {
    margin: 0 auto;

    width: 420px;
  }
  .bocdd {
    width: 200px;
    margin: 20px auto;
    text-align: center;
  }

  .msx {
    height: 100px;
    width: 2px;
    background-color: blue;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
  .bocdds .arco-btn {
    margin: 5px 10px;
  }
</style>
